package flights.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import flights.bi.Booking;
import flights.bi.Flight_Seat;
import flights.bi.Ticket;
import flights.db.BookingHandler;
import flights.db.FlightSeatHandler;
import flights.db.TicketHandler;

/**
 * Servlet implementation class BookingServlet
 */
public class BookingServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public BookingServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		PrintWriter out = response.getWriter();
		String url = request.getPathInfo();
		response.setContentType( "text/html" ); 
		if (url != null && url.indexOf("getbooking") != -1)
		{
			String uid = request.getParameter("uid");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			List<Booking> bookings = null;
			try {
				bookings = BookingHandler.getAllUserBookings(Integer.parseInt(uid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(bookings));	
		}
		else if (url != null && url.indexOf("getseats") != -1)
		{
			String bid = request.getParameter("bid");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			List<Flight_Seat> seats = null;
			try {
				seats = FlightSeatHandler.getAllSeatsByBooking(Integer.parseInt(bid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(seats));	
		}
		else if (url != null && url.indexOf("gettickets") != -1)
		{
			String bid = request.getParameter("bid");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			List<Ticket> tickets = null;
			try {
				tickets = TicketHandler.getAllTicketsByBooking(Integer.parseInt(bid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(tickets));	
		}
		else if (url != null && url.indexOf("getcost") != -1)
		{
			String uid = request.getParameter("uid");
			int nCost = 0;
			try {
				nCost = BookingHandler.getUserBookingCostByID(Integer.parseInt(uid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print("{\"total_cost\": " + nCost + "}");	
		}
		else if (url != null && url.indexOf("sumorders") != -1)
		{
			String uid = request.getParameter("uid");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			Map<String, Integer> mpResult = null;
			try {
				mpResult = BookingHandler.getBookingByMonthsForUser(Integer.parseInt(uid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(mpResult));	
		}
		else if (url != null && url.indexOf("makebooking") != -1)
		{
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			String bookingJson = request.getParameter("booking");
			if (bookingJson != null && !bookingJson.isEmpty()) {
				
				Type flightType = new TypeToken<Booking>(){}.getType();
				Booking booking = gson.fromJson(bookingJson, flightType);
				
				int nRows = 0;
				try {
					nRows = BookingHandler.upsertBooking(booking);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				out.write("{\"rows\":" + nRows + "}");
			}	
		}
		else if (url != null && url.indexOf("remove") != -1)
		{
			String bid = request.getParameter("bid");
			int nRows = 0;
			try {
				nRows = BookingHandler.deleteBookingByID(Integer.parseInt(bid));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print("{\"rows\": " + nRows + "}");	
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		String url = request.getPathInfo();
		List<Integer> generatedSeatKeys = new ArrayList<Integer>();
		response.setContentType( "text/html" );
		int nRows = 0;
		if (url != null && url.indexOf("book") != -1)
		{
			//Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			try {
				StringBuilder sb = new StringBuilder();
			    BufferedReader br = request.getReader();
			    String str;
			    
			    while( (str = br.readLine()) != null ){
			        sb.append(str);
			    }    
			    
			    JSONObject jObj = new JSONObject(sb.toString());
				
				int seatsCount = jObj.getInt("seats_count");
				int user_id = jObj.getInt("user_id");
				int flight_id = jObj.getInt("flight_id");
				String seats_class = jObj.getString("seats_class");
				//generatedSeatKeys = FlightSeatHandler.generateSeats(flight_id, seatCost, seats_class, seatsCount);
				generatedSeatKeys = FlightSeatHandler.getSeatsByParams(flight_id, seats_class, seatsCount);
				java.util.Date today = new java.util.Date();
				java.sql.Date sqlToday = new java.sql.Date(today.getTime());
				Booking bk = new Booking(-1, user_id, 1, sqlToday);
				int generatedBookingKeys = BookingHandler.upsertBooking(bk);
				
				JSONArray array = jObj.getJSONArray("users"); 
				for (Integer seat_id : generatedSeatKeys) {
					 JSONObject jUsers = array.getJSONObject(nRows);
					 nRows++;
					Ticket t = new Ticket(-1, jUsers.getString("passport_number"), jUsers.getString("first_name"), jUsers.getString("last_name"), seat_id, null, generatedBookingKeys);
					TicketHandler.upsertTicket(t);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
			out.print("{\"rows\": " + nRows + "}");	
		}
	}

}
